//////////////////////////////////////////////////////////////////////
////                                                              ////
////  CardInfo.v                                                  ////
////                                                              ////
////                                                              ////
////  This file is part of the "Pico E12" project                 ////
////  http://www.picocomputing.com                                ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2005, Picocomputing, Inc.                      ////
//// http://www.picocomputing.com/                                ////
////                                                              ////
////////////////////////////////////////////////////////////////////JF


`timescale 10ns / 1ps
//This module returns some information about the card.
//This really should be implemented as a ROM (although ISE optimizes this unit nicely)

`include "PicoDefines.v"

`define VERSION_LOWER_LOWER_ADDRESS      10'h200
`define VERSION_LOWER_UPPER_ADDRESS      10'h201
`define VERSION_UPPER_LOWER_ADDRESS      10'h202
`define VERSION_UPPER_UPPER_ADDRESS      10'h203

`define IMAGE_CAPABILITIES_LOWER_ADDRESS 10'h204
`define IMAGE_CAPABILITIES_UPPER_ADDRESS 10'h205


//--------------------------------- Card Capabilities
// Capability definitions used to tell software what the fpga image can do.
// To indicate the capabilities an image has, define IMAGE_CAPABILITIES in PicoDefines.v.
//   For example: `define IMAGE_CAPABILITIES (`PICO_CAP_FLASH | `PICO_CAP_TURBOLOADER)

// No capabilities unless explicitly specified. We can't assume anything, since it's possible for
//   someone to instantiate us and, for example, not actually connect the flash lines.
`ifndef IMAGE_CAPABILITIES
   `define IMAGE_CAPABILITIES        0
`endif


module CardInfo(AttribRead, MemAddress, DataOut);

input AttribRead;
input [10:1]MemAddress;
output [15:0]DataOut;

wire AttribReadBUF;

wire VersionUpperUpper;                                 //Version Byte [4]
wire VersionUpperLower;                                 //Version Byte [3]
wire VersionLowerUpper;                                 //Version Byte [2]
wire VersionLowerLower;                                 //Version Byte [1]
wire ImageCapabilitiesUpper;                            //Image Capabilities Byte [2]
wire ImageCapabilitiesLower;                            //Image Capabilities Byte [1]

wire [7:0]VersionUpperUpperOut;
wire [7:0]VersionUpperLowerOut;
wire [7:0]VersionLowerUpperOut;
wire [7:0]VersionLowerLowerOut;

wire [7:0]ImageCapabilitiesUpperOut;
wire [7:0]ImageCapabilitiesLowerOut;

BUF AttribReadBuffer(.I(AttribRead), .O(AttribReadBUF));         //Buffer AttribRead from a clock distribution line for use with logic

assign DataOut[7:0] = (VersionLowerLowerOut[7:0] | VersionLowerUpperOut[7:0] | VersionUpperLowerOut[7:0] | VersionUpperUpperOut[7:0] |
                       ImageCapabilitiesLowerOut[7:0] | ImageCapabilitiesUpperOut[7:0]);

assign DataOut[15:8] = DataOut[7:0];

assign VersionLowerLower = (AttribReadBUF) && (MemAddress[10:1] == `VERSION_LOWER_LOWER_ADDRESS);
assign VersionLowerUpper = (AttribReadBUF) && (MemAddress[10:1] == `VERSION_LOWER_UPPER_ADDRESS);
assign VersionUpperLower = (AttribReadBUF) && (MemAddress[10:1] == `VERSION_UPPER_LOWER_ADDRESS);
assign VersionUpperUpper = (AttribReadBUF) && (MemAddress[10:1] == `VERSION_UPPER_UPPER_ADDRESS);
assign ImageCapabilitiesLower = (AttribReadBUF) && (MemAddress[10:1] == `IMAGE_CAPABILITIES_LOWER_ADDRESS);
assign ImageCapabilitiesUpper = (AttribReadBUF) && (MemAddress[10:1] == `IMAGE_CAPABILITIES_UPPER_ADDRESS);

assign VersionLowerLowerOut[7:0] = (VersionLowerLower)?`VERSION_LOWER_LOWER : 8'b0;
assign VersionLowerUpperOut[7:0] = (VersionLowerUpper)?`VERSION_LOWER_UPPER : 8'b0;
assign VersionUpperLowerOut[7:0] = (VersionUpperLower)?`VERSION_UPPER_LOWER : 8'b0;
assign VersionUpperUpperOut[7:0] = (VersionUpperUpper)?`VERSION_UPPER_UPPER : 8'b0;

// This wire exists only to facilitate splitting the capabilities into two bytes.
wire [15:0]image_capabilities_wire;
assign image_capabilities_wire = `IMAGE_CAPABILITIES;
assign ImageCapabilitiesLowerOut[7:0] = (ImageCapabilitiesLower) ? image_capabilities_wire[7:0] : 8'b0;
assign ImageCapabilitiesUpperOut[7:0] = (ImageCapabilitiesUpper) ? image_capabilities_wire[15:8] : 8'b0;

endmodule